# -*- coding: utf-8 -*-
#
# Copyright 2017 zhangxp, st
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from rqalpha.interface import AbstractMod
from rqalpha.api import export_as_api
from rqalpha.utils.arg_checker import apply_rules, verify_that

from rqalpha.const import EXECUTION_PHASE

from rqalpha.core.execution_context import ExecutionContext

from .plot_store import PlotStore

this = None

@export_as_api
@ExecutionContext.enforce_phase(
    EXECUTION_PHASE.ON_INIT
)
def plot_init(security):
    # type: (str) -> None
    """
    在策略运行结束后的收益图中，加入自定义的曲线。
    每次调用 plot 函数将会以当前时间为横坐标，value 为纵坐标加入一个点，series_name 相同的点将连成一条曲线。

    :param series_name: 曲线名称
    :param value: 点的纵坐标值

    :example:

    .. code-block:: python

        def handle_bar(context, bar_dict):
            plot("OPEN", bar_dict["000001.XSHE"].open)

    """
    this.init(security)


@export_as_api
@ExecutionContext.enforce_phase(
    EXECUTION_PHASE.ON_BAR, EXECUTION_PHASE.ON_TICK, EXECUTION_PHASE.SCHEDULED
)
def plot_kline(bar):
    # type: (dict) -> None
    """
    在策略运行结束后的收益图中，加入自定义的曲线。
    每次调用 plot 函数将会以当前时间为横坐标，value 为纵坐标加入一个点，series_name 相同的点将连成一条曲线。

    :param series_name: 曲线名称
    :param value: 点的纵坐标值

    :example:

    .. code-block:: python

        def handle_bar(context, bar_dict):
            plot("OPEN", bar_dict["000001.XSHE"].open)

    """
    this.add_kline(this._env.trading_dt, bar.open, bar.high, bar.low, bar.close)


@export_as_api
@ExecutionContext.enforce_phase(
    EXECUTION_PHASE.ON_BAR, EXECUTION_PHASE.ON_TICK, EXECUTION_PHASE.SCHEDULED
)
@apply_rules(
    verify_that("order_type", pre_check=True).is_instance_of(str),
    verify_that("value", pre_check=True).is_number(),
)
def plot_order(order_type, value):
    # type: (str, float) -> None
    """
    在策略运行结束后的收益图中，加入自定义的曲线。
    每次调用 plot 函数将会以当前时间为横坐标，value 为纵坐标加入一个点，series_name 相同的点将连成一条曲线。

    :param series_name: 曲线名称
    :param value: 点的纵坐标值

    :example:

    .. code-block:: python

        def handle_bar(context, bar_dict):
            plot("OPEN", bar_dict["000001.XSHE"].open)

    """
    this.add_plot(this._env.trading_dt, 'ORDER', {order_type: value})

@export_as_api
@ExecutionContext.enforce_phase(
    EXECUTION_PHASE.ON_BAR, EXECUTION_PHASE.ON_TICK, EXECUTION_PHASE.SCHEDULED
)
@apply_rules(
    verify_that("line_name", pre_check=True).is_instance_of(str),
    verify_that("value", pre_check=True).is_number(),
)
def plot_line(line_name, value):
    # type: (str, float) -> None
    """
    在策略运行结束后的收益图中，加入自定义的曲线。
    每次调用 plot 函数将会以当前时间为横坐标，value 为纵坐标加入一个点，series_name 相同的点将连成一条曲线。

    :param series_name: 曲线名称
    :param value: 点的纵坐标值

    :example:

    .. code-block:: python

        def handle_bar(context, bar_dict):
            plot("OPEN", bar_dict["000001.XSHE"].open)

    """
    this.add_plot(this._env.trading_dt, 'LINE', {line_name: value})

@export_as_api
@ExecutionContext.enforce_phase(
    EXECUTION_PHASE.ON_BAR, EXECUTION_PHASE.ON_TICK, EXECUTION_PHASE.SCHEDULED
)
@apply_rules(
    verify_that("text", pre_check=True).is_instance_of(str),
)
def plot_text(text):
    # type: (str) -> None
    """
    在策略运行结束后的收益图中，加入自定义的曲线。
    每次调用 plot 函数将会以当前时间为横坐标，value 为纵坐标加入一个点，series_name 相同的点将连成一条曲线。

    :param series_name: 曲线名称
    :param value: 点的纵坐标值

    :example:

    .. code-block:: python

        def handle_bar(context, bar_dict):
            plot("OPEN", bar_dict["000001.XSHE"].open)

    """
    this.add_plot(this._env.trading_dt, 'TEXT', text)

@export_as_api        
@ExecutionContext.enforce_phase(
    EXECUTION_PHASE.ON_BAR, EXECUTION_PHASE.ON_TICK, EXECUTION_PHASE.SCHEDULED
)
@apply_rules(
    verify_that("value", pre_check=True).is_number(),
)
def plot_icon(value):
    # type: (int) -> None
    """
    在策略运行结束后的收益图中，加入自定义的曲线。
    每次调用 plot 函数将会以当前时间为横坐标，value 为纵坐标加入一个点，series_name 相同的点将连成一条曲线。

    :param series_name: 曲线名称
    :param value: 点的纵坐标值

    :example:

    .. code-block:: python

        def handle_bar(context, bar_dict):
            plot("OPEN", bar_dict["000001.XSHE"].open)

    """
    this.add_plot(this._env.trading_dt, 'ICON', value)


class StuPlotMod(AbstractMod):
    def __init__(self):
        pass

    def start_up(self, env, mod_config):
        global this
        # 数据库参数
        if 'to_sql' in mod_config:
            if 'user' in mod_config and 'password' in mod_config and 'host' in mod_config and 'port' in mod_config:
                conn_dsn = 'mysql+pymysql://%s:%s@%s:%s/nextt?charset=utf8' % \
                    (mod_config.user, mod_config.password, mod_config.host, mod_config.port)
                this = PlotStore(to_sql=mod_config.to_sql, conn_dsn=conn_dsn)
            else:
                this = PlotStore(to_sql=mod_config.to_sql)
        else:
            this = PlotStore()

    def tear_down(self, code, exception=None):
        pass
